/**
 * 通知管理器
 * 处理应用内通知、提醒和消息
 */

import { getSettings } from './settingsManager.js'

/**
 * 通知类型枚举
 */
export const NotificationType = {
	ACHIEVEMENT: 'achievement',
	DAILY_REMINDER: 'daily_reminder',
	TEST_COMPLETE: 'test_complete',
	STREAK_MILESTONE: 'streak_milestone',
	PERSONAL_BEST: 'personal_best',
	CHALLENGE: 'challenge',
	SYSTEM: 'system'
}

/**
 * 通知优先级
 */
export const NotificationPriority = {
	LOW: 1,
	NORMAL: 2,
	HIGH: 3,
	URGENT: 4
}

/**
 * 通知管理器类
 */
class NotificationManager {
	constructor() {
		this.notifications = []
		this.listeners = []
		this.loadNotifications()
	}
	
	/**
	 * 加载本地通知
	 */
	loadNotifications() {
		try {
			this.notifications = uni.getStorageSync('notifications') || []
			// 清理过期通知
			this.cleanExpiredNotifications()
		} catch (error) {
			console.error('加载通知失败:', error)
			this.notifications = []
		}
	}
	
	/**
	 * 保存通知到本地
	 */
	saveNotifications() {
		try {
			uni.setStorageSync('notifications', this.notifications)
		} catch (error) {
			console.error('保存通知失败:', error)
		}
	}
	
	/**
	 * 创建通知
	 * @param {Object} options - 通知选项
	 * @returns {string} 通知ID
	 */
	createNotification(options) {
		const {
			type,
			title,
			message,
			priority = NotificationPriority.NORMAL,
			data = {},
			expireTime = null,
			actionable = false,
			actions = []
		} = options
		
		const notification = {
			id: this.generateId(),
			type,
			title,
			message,
			priority,
			data,
			createdAt: new Date().toISOString(),
			expireTime,
			read: false,
			actionable,
			actions,
			dismissed: false
		}
		
		this.notifications.unshift(notification)
		this.saveNotifications()
		
		// 通知监听器
		this.notifyListeners('created', notification)
		
		// 显示通知
		this.showNotification(notification)
		
		return notification.id
	}
	
	/**
	 * 显示通知
	 * @param {Object} notification - 通知对象
	 */
	showNotification(notification) {
		const settings = getSettings()
		
		// 检查通知设置
		if (!this.shouldShowNotification(notification.type, settings)) {
			return
		}
		
		// 根据优先级选择显示方式
		switch (notification.priority) {
			case NotificationPriority.URGENT:
				this.showModal(notification)
				break
			case NotificationPriority.HIGH:
				this.showToast(notification)
				break
			default:
				// 普通和低优先级通知只在通知中心显示
				break
		}
	}
	
	/**
	 * 检查是否应该显示通知
	 * @param {string} type - 通知类型
	 * @param {Object} settings - 用户设置
	 * @returns {boolean}
	 */
	shouldShowNotification(type, settings) {
		switch (type) {
			case NotificationType.ACHIEVEMENT:
				return settings.notifications?.achievementNotifications !== false
			case NotificationType.DAILY_REMINDER:
				return settings.notifications?.dailyReminder !== false
			case NotificationType.TEST_COMPLETE:
				return settings.notifications?.testComplete !== false
			default:
				return true
		}
	}
	
	/**
	 * 显示模态通知
	 * @param {Object} notification - 通知对象
	 */
	showModal(notification) {
		uni.showModal({
			title: notification.title,
			content: notification.message,
			showCancel: notification.actionable,
			confirmText: notification.actions[0]?.text || '确定',
			cancelText: notification.actions[1]?.text || '取消',
			success: (res) => {
				if (res.confirm && notification.actions[0]?.callback) {
					notification.actions[0].callback(notification)
				} else if (res.cancel && notification.actions[1]?.callback) {
					notification.actions[1].callback(notification)
				}
				this.markAsRead(notification.id)
			}
		})
	}
	
	/**
	 * 显示Toast通知
	 * @param {Object} notification - 通知对象
	 */
	showToast(notification) {
		uni.showToast({
			title: notification.title,
			icon: this.getToastIcon(notification.type),
			duration: 3000
		})
		
		// 自动标记为已读
		setTimeout(() => {
			this.markAsRead(notification.id)
		}, 3000)
	}
	
	/**
	 * 获取Toast图标
	 * @param {string} type - 通知类型
	 * @returns {string}
	 */
	getToastIcon(type) {
		switch (type) {
			case NotificationType.ACHIEVEMENT:
				return 'success'
			case NotificationType.PERSONAL_BEST:
				return 'success'
			case NotificationType.STREAK_MILESTONE:
				return 'success'
			default:
				return 'none'
		}
	}
	
	/**
	 * 标记通知为已读
	 * @param {string} notificationId - 通知ID
	 */
	markAsRead(notificationId) {
		const notification = this.notifications.find(n => n.id === notificationId)
		if (notification) {
			notification.read = true
			this.saveNotifications()
			this.notifyListeners('read', notification)
		}
	}
	
	/**
	 * 标记所有通知为已读
	 */
	markAllAsRead() {
		this.notifications.forEach(notification => {
			notification.read = true
		})
		this.saveNotifications()
		this.notifyListeners('allRead')
	}
	
	/**
	 * 删除通知
	 * @param {string} notificationId - 通知ID
	 */
	deleteNotification(notificationId) {
		const index = this.notifications.findIndex(n => n.id === notificationId)
		if (index > -1) {
			const notification = this.notifications[index]
			this.notifications.splice(index, 1)
			this.saveNotifications()
			this.notifyListeners('deleted', notification)
		}
	}
	
	/**
	 * 清空所有通知
	 */
	clearAllNotifications() {
		this.notifications = []
		this.saveNotifications()
		this.notifyListeners('cleared')
	}
	
	/**
	 * 获取通知列表
	 * @param {Object} options - 筛选选项
	 * @returns {Array} 通知列表
	 */
	getNotifications(options = {}) {
		const {
			type = null,
			unreadOnly = false,
			limit = null,
			offset = 0
		} = options
		
		let filtered = [...this.notifications]
		
		// 按类型筛选
		if (type) {
			filtered = filtered.filter(n => n.type === type)
		}
		
		// 只显示未读
		if (unreadOnly) {
			filtered = filtered.filter(n => !n.read)
		}
		
		// 分页
		if (limit) {
			filtered = filtered.slice(offset, offset + limit)
		}
		
		return filtered
	}
	
	/**
	 * 获取未读通知数量
	 * @returns {number}
	 */
	getUnreadCount() {
		return this.notifications.filter(n => !n.read).length
	}
	
	/**
	 * 清理过期通知
	 */
	cleanExpiredNotifications() {
		const now = new Date()
		const initialCount = this.notifications.length
		
		this.notifications = this.notifications.filter(notification => {
			if (!notification.expireTime) return true
			return new Date(notification.expireTime) > now
		})
		
		if (this.notifications.length < initialCount) {
			this.saveNotifications()
		}
	}
	
	/**
	 * 添加监听器
	 * @param {Function} listener - 监听器函数
	 */
	addListener(listener) {
		this.listeners.push(listener)
	}
	
	/**
	 * 移除监听器
	 * @param {Function} listener - 监听器函数
	 */
	removeListener(listener) {
		const index = this.listeners.indexOf(listener)
		if (index > -1) {
			this.listeners.splice(index, 1)
		}
	}
	
	/**
	 * 通知监听器
	 * @param {string} event - 事件类型
	 * @param {Object} data - 事件数据
	 */
	notifyListeners(event, data) {
		this.listeners.forEach(listener => {
			try {
				listener(event, data)
			} catch (error) {
				console.error('通知监听器错误:', error)
			}
		})
	}
	
	/**
	 * 生成唯一ID
	 * @returns {string}
	 */
	generateId() {
		return Date.now().toString(36) + Math.random().toString(36).substr(2)
	}
}

// 创建全局实例
const notificationManager = new NotificationManager()

/**
 * 便捷方法：创建成就通知
 * @param {Object} achievement - 成就对象
 */
export function notifyAchievement(achievement) {
	return notificationManager.createNotification({
		type: NotificationType.ACHIEVEMENT,
		title: '🏆 成就解锁！',
		message: `恭喜获得成就：${achievement.name}`,
		priority: NotificationPriority.HIGH,
		data: { achievement },
		actionable: true,
		actions: [
			{
				text: '查看',
				callback: () => {
					uni.navigateTo({
						url: '/pages/profile/profile'
					})
				}
			},
			{ text: '关闭' }
		]
	})
}

/**
 * 便捷方法：创建个人最佳通知
 * @param {Object} testResult - 测试结果
 */
export function notifyPersonalBest(testResult) {
	return notificationManager.createNotification({
		type: NotificationType.PERSONAL_BEST,
		title: '🎉 新纪录！',
		message: `在${testResult.testType}测试中创造了新的个人最佳成绩：${testResult.score}分`,
		priority: NotificationPriority.HIGH,
		data: { testResult }
	})
}

/**
 * 便捷方法：创建连续测试里程碑通知
 * @param {number} streak - 连续天数
 */
export function notifyStreakMilestone(streak) {
	return notificationManager.createNotification({
		type: NotificationType.STREAK_MILESTONE,
		title: '🔥 连续挑战！',
		message: `已连续${streak}天完成测试，继续保持！`,
		priority: NotificationPriority.NORMAL,
		data: { streak }
	})
}

/**
 * 便捷方法：创建测试完成通知
 * @param {Object} testResult - 测试结果
 */
export function notifyTestComplete(testResult) {
	return notificationManager.createNotification({
		type: NotificationType.TEST_COMPLETE,
		title: '✅ 测试完成',
		message: `${testResult.testType}测试完成，得分：${testResult.score}`,
		priority: NotificationPriority.LOW,
		data: { testResult }
	})
}

/**
 * 便捷方法：创建每日提醒通知
 */
export function notifyDailyReminder() {
	return notificationManager.createNotification({
		type: NotificationType.DAILY_REMINDER,
		title: '🧠 每日训练',
		message: '该进行今天的脑力训练了！',
		priority: NotificationPriority.NORMAL,
		actionable: true,
		actions: [
			{
				text: '开始训练',
				callback: () => {
					uni.switchTab({
						url: '/pages/index/index'
					})
				}
			},
			{ text: '稍后提醒' }
		]
	})
}

/**
 * 便捷方法：创建挑战通知
 * @param {Object} challenge - 挑战对象
 */
export function notifyChallenge(challenge) {
	return notificationManager.createNotification({
		type: NotificationType.CHALLENGE,
		title: '⚔️ 新挑战',
		message: `${challenge.challenger}向你发起了${challenge.testType}挑战！`,
		priority: NotificationPriority.HIGH,
		data: { challenge },
		actionable: true,
		actions: [
			{
				text: '接受',
				callback: (notification) => {
					// 处理接受挑战逻辑
					console.log('接受挑战:', notification.data.challenge)
				}
			},
			{
				text: '拒绝',
				callback: (notification) => {
					// 处理拒绝挑战逻辑
					console.log('拒绝挑战:', notification.data.challenge)
				}
			}
		]
	})
}

/**
 * 便捷方法：创建系统通知
 * @param {string} title - 标题
 * @param {string} message - 消息
 * @param {number} priority - 优先级
 */
export function notifySystem(title, message, priority = NotificationPriority.NORMAL) {
	return notificationManager.createNotification({
		type: NotificationType.SYSTEM,
		title,
		message,
		priority
	})
}

/**
 * 设置每日提醒
 * @param {string} time - 提醒时间 (HH:MM)
 */
export function scheduleDailyReminder(time) {
	try {
		// 在实际应用中，这里应该使用系统的定时通知API
		// 由于小程序的限制，这里只是一个示例实现
		
		const [hours, minutes] = time.split(':').map(Number)
		const now = new Date()
		const reminderTime = new Date()
		reminderTime.setHours(hours, minutes, 0, 0)
		
		// 如果时间已过，设置为明天
		if (reminderTime <= now) {
			reminderTime.setDate(reminderTime.getDate() + 1)
		}
		
		const delay = reminderTime.getTime() - now.getTime()
		
		setTimeout(() => {
			notifyDailyReminder()
			// 设置下一天的提醒
			scheduleDailyReminder(time)
		}, delay)
		
		console.log(`每日提醒已设置：${time}，下次提醒时间：${reminderTime.toLocaleString()}`)
	} catch (error) {
		console.error('设置每日提醒失败:', error)
	}
}

/**
 * 取消每日提醒
 */
export function cancelDailyReminder() {
	// 在实际应用中，这里应该取消系统定时通知
	console.log('每日提醒已取消')
}

// 导出通知管理器实例
export default notificationManager